// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <OnionPeelAttributes.h>
#include <DataNode.h>

//
// Enum conversion methods for OnionPeelAttributes::NodeFace
//

static const char *NodeFace_strings[] = {
"Node", "Face"};

std::string
OnionPeelAttributes::NodeFace_ToString(OnionPeelAttributes::NodeFace t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return NodeFace_strings[index];
}

std::string
OnionPeelAttributes::NodeFace_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return NodeFace_strings[index];
}

bool
OnionPeelAttributes::NodeFace_FromString(const std::string &s, OnionPeelAttributes::NodeFace &val)
{
    val = OnionPeelAttributes::Node;
    for(int i = 0; i < 2; ++i)
    {
        if(s == NodeFace_strings[i])
        {
            val = (NodeFace)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for OnionPeelAttributes::SeedIdType
//

static const char *SeedIdType_strings[] = {
"SeedCell", "SeedNode"};

std::string
OnionPeelAttributes::SeedIdType_ToString(OnionPeelAttributes::SeedIdType t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return SeedIdType_strings[index];
}

std::string
OnionPeelAttributes::SeedIdType_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return SeedIdType_strings[index];
}

bool
OnionPeelAttributes::SeedIdType_FromString(const std::string &s, OnionPeelAttributes::SeedIdType &val)
{
    val = OnionPeelAttributes::SeedCell;
    for(int i = 0; i < 2; ++i)
    {
        if(s == SeedIdType_strings[i])
        {
            val = (SeedIdType)i;
            return true;
        }
    }
    return false;
}

// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Init utility for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void OnionPeelAttributes::Init()
{
    adjacencyType = Node;
    useGlobalId = false;
    categoryName = "Whole";
    subsetName = "Whole";
    index.push_back(0);
    logical = false;
    requestedLayer = 0;
    seedType = SeedCell;
    honorOriginalMesh = true;

    OnionPeelAttributes::SelectAll();
}

// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Copy utility for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void OnionPeelAttributes::Copy(const OnionPeelAttributes &obj)
{
    adjacencyType = obj.adjacencyType;
    useGlobalId = obj.useGlobalId;
    categoryName = obj.categoryName;
    subsetName = obj.subsetName;
    index = obj.index;
    logical = obj.logical;
    requestedLayer = obj.requestedLayer;
    seedType = obj.seedType;
    honorOriginalMesh = obj.honorOriginalMesh;

    OnionPeelAttributes::SelectAll();
}

// Type map format string
const char *OnionPeelAttributes::TypeMapFormatString = ONIONPEELATTRIBUTES_TMFS;
const AttributeGroup::private_tmfs_t OnionPeelAttributes::TmfsStruct = {ONIONPEELATTRIBUTES_TMFS};


// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Default constructor for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes::OnionPeelAttributes() :
    AttributeSubject(OnionPeelAttributes::TypeMapFormatString)
{
    OnionPeelAttributes::Init();
}

// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Constructor for the derived classes of OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes::OnionPeelAttributes(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    OnionPeelAttributes::Init();
}

// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Copy constructor for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes::OnionPeelAttributes(const OnionPeelAttributes &obj) :
    AttributeSubject(OnionPeelAttributes::TypeMapFormatString)
{
    OnionPeelAttributes::Copy(obj);
}

// ****************************************************************************
// Method: OnionPeelAttributes::OnionPeelAttributes
//
// Purpose:
//   Copy constructor for derived classes of the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes::OnionPeelAttributes(const OnionPeelAttributes &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    OnionPeelAttributes::Copy(obj);
}

// ****************************************************************************
// Method: OnionPeelAttributes::~OnionPeelAttributes
//
// Purpose:
//   Destructor for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes::~OnionPeelAttributes()
{
    // nothing here
}

// ****************************************************************************
// Method: OnionPeelAttributes::operator =
//
// Purpose:
//   Assignment operator for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

OnionPeelAttributes&
OnionPeelAttributes::operator = (const OnionPeelAttributes &obj)
{
    if (this == &obj) return *this;

    OnionPeelAttributes::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: OnionPeelAttributes::operator ==
//
// Purpose:
//   Comparison operator == for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
OnionPeelAttributes::operator == (const OnionPeelAttributes &obj) const
{
    // Create the return value
    return ((adjacencyType == obj.adjacencyType) &&
            (useGlobalId == obj.useGlobalId) &&
            (categoryName == obj.categoryName) &&
            (subsetName == obj.subsetName) &&
            (index == obj.index) &&
            (logical == obj.logical) &&
            (requestedLayer == obj.requestedLayer) &&
            (seedType == obj.seedType) &&
            (honorOriginalMesh == obj.honorOriginalMesh));
}

// ****************************************************************************
// Method: OnionPeelAttributes::operator !=
//
// Purpose:
//   Comparison operator != for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
OnionPeelAttributes::operator != (const OnionPeelAttributes &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: OnionPeelAttributes::TypeName
//
// Purpose:
//   Type name method for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
OnionPeelAttributes::TypeName() const
{
    return "OnionPeelAttributes";
}

// ****************************************************************************
// Method: OnionPeelAttributes::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
OnionPeelAttributes::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const OnionPeelAttributes *tmp = (const OnionPeelAttributes *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: OnionPeelAttributes::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
OnionPeelAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new OnionPeelAttributes(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: OnionPeelAttributes::NewInstance
//
// Purpose:
//   NewInstance method for the OnionPeelAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
OnionPeelAttributes::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new OnionPeelAttributes(*this);
    else
        retval = new OnionPeelAttributes;

    return retval;
}

// ****************************************************************************
// Method: OnionPeelAttributes::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
OnionPeelAttributes::SelectAll()
{
    Select(ID_adjacencyType,     (void *)&adjacencyType);
    Select(ID_useGlobalId,       (void *)&useGlobalId);
    Select(ID_categoryName,      (void *)&categoryName);
    Select(ID_subsetName,        (void *)&subsetName);
    Select(ID_index,             (void *)&index);
    Select(ID_logical,           (void *)&logical);
    Select(ID_requestedLayer,    (void *)&requestedLayer);
    Select(ID_seedType,          (void *)&seedType);
    Select(ID_honorOriginalMesh, (void *)&honorOriginalMesh);
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: OnionPeelAttributes::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
OnionPeelAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    OnionPeelAttributes defaultObject;
    bool addToParent = false;
    // Create a node for OnionPeelAttributes.
    DataNode *node = new DataNode("OnionPeelAttributes");

    if(completeSave || !FieldsEqual(ID_adjacencyType, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("adjacencyType", NodeFace_ToString(adjacencyType)));
    }

    if(completeSave || !FieldsEqual(ID_useGlobalId, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("useGlobalId", useGlobalId));
    }

    if(completeSave || !FieldsEqual(ID_categoryName, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("categoryName", categoryName));
    }

    if(completeSave || !FieldsEqual(ID_subsetName, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("subsetName", subsetName));
    }

    if(completeSave || !FieldsEqual(ID_index, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("index", index));
    }

    if(completeSave || !FieldsEqual(ID_logical, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("logical", logical));
    }

    if(completeSave || !FieldsEqual(ID_requestedLayer, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("requestedLayer", requestedLayer));
    }

    if(completeSave || !FieldsEqual(ID_seedType, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("seedType", SeedIdType_ToString(seedType)));
    }

    if(completeSave || !FieldsEqual(ID_honorOriginalMesh, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("honorOriginalMesh", honorOriginalMesh));
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: OnionPeelAttributes::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode representation of the object.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
OnionPeelAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("OnionPeelAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("adjacencyType")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 2)
                SetAdjacencyType(NodeFace(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            NodeFace value;
            if(NodeFace_FromString(node->AsString(), value))
                SetAdjacencyType(value);
        }
    }
    if((node = searchNode->GetNode("useGlobalId")) != 0)
        SetUseGlobalId(node->AsBool());
    if((node = searchNode->GetNode("categoryName")) != 0)
        SetCategoryName(node->AsString());
    if((node = searchNode->GetNode("subsetName")) != 0)
        SetSubsetName(node->AsString());
    if((node = searchNode->GetNode("index")) != 0)
        SetIndex(node->AsIntVector());
    if((node = searchNode->GetNode("logical")) != 0)
        SetLogical(node->AsBool());
    if((node = searchNode->GetNode("requestedLayer")) != 0)
        SetRequestedLayer(node->AsInt());
    if((node = searchNode->GetNode("seedType")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 2)
                SetSeedType(SeedIdType(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            SeedIdType value;
            if(SeedIdType_FromString(node->AsString(), value))
                SetSeedType(value);
        }
    }
    if((node = searchNode->GetNode("honorOriginalMesh")) != 0)
        SetHonorOriginalMesh(node->AsBool());
}

///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
OnionPeelAttributes::SetAdjacencyType(OnionPeelAttributes::NodeFace adjacencyType_)
{
    adjacencyType = adjacencyType_;
    Select(ID_adjacencyType, (void *)&adjacencyType);
}

void
OnionPeelAttributes::SetUseGlobalId(bool useGlobalId_)
{
    useGlobalId = useGlobalId_;
    Select(ID_useGlobalId, (void *)&useGlobalId);
}

void
OnionPeelAttributes::SetCategoryName(const std::string &categoryName_)
{
    categoryName = categoryName_;
    Select(ID_categoryName, (void *)&categoryName);
}

void
OnionPeelAttributes::SetSubsetName(const std::string &subsetName_)
{
    subsetName = subsetName_;
    Select(ID_subsetName, (void *)&subsetName);
}

void
OnionPeelAttributes::SetIndex(const intVector &index_)
{
    index = index_;
    Select(ID_index, (void *)&index);
}

void
OnionPeelAttributes::SetLogical(bool logical_)
{
    logical = logical_;
    Select(ID_logical, (void *)&logical);
}

void
OnionPeelAttributes::SetRequestedLayer(int requestedLayer_)
{
    requestedLayer = requestedLayer_;
    Select(ID_requestedLayer, (void *)&requestedLayer);
}

void
OnionPeelAttributes::SetSeedType(OnionPeelAttributes::SeedIdType seedType_)
{
    seedType = seedType_;
    Select(ID_seedType, (void *)&seedType);
}

void
OnionPeelAttributes::SetHonorOriginalMesh(bool honorOriginalMesh_)
{
    honorOriginalMesh = honorOriginalMesh_;
    Select(ID_honorOriginalMesh, (void *)&honorOriginalMesh);
}

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

OnionPeelAttributes::NodeFace
OnionPeelAttributes::GetAdjacencyType() const
{
    return NodeFace(adjacencyType);
}

bool
OnionPeelAttributes::GetUseGlobalId() const
{
    return useGlobalId;
}

const std::string &
OnionPeelAttributes::GetCategoryName() const
{
    return categoryName;
}

std::string &
OnionPeelAttributes::GetCategoryName()
{
    return categoryName;
}

const std::string &
OnionPeelAttributes::GetSubsetName() const
{
    return subsetName;
}

std::string &
OnionPeelAttributes::GetSubsetName()
{
    return subsetName;
}

const intVector &
OnionPeelAttributes::GetIndex() const
{
    return index;
}

intVector &
OnionPeelAttributes::GetIndex()
{
    return index;
}

bool
OnionPeelAttributes::GetLogical() const
{
    return logical;
}

int
OnionPeelAttributes::GetRequestedLayer() const
{
    return requestedLayer;
}

OnionPeelAttributes::SeedIdType
OnionPeelAttributes::GetSeedType() const
{
    return SeedIdType(seedType);
}

bool
OnionPeelAttributes::GetHonorOriginalMesh() const
{
    return honorOriginalMesh;
}

///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////

void
OnionPeelAttributes::SelectCategoryName()
{
    Select(ID_categoryName, (void *)&categoryName);
}

void
OnionPeelAttributes::SelectSubsetName()
{
    Select(ID_subsetName, (void *)&subsetName);
}

void
OnionPeelAttributes::SelectIndex()
{
    Select(ID_index, (void *)&index);
}

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: OnionPeelAttributes::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
OnionPeelAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_adjacencyType:     return "adjacencyType";
    case ID_useGlobalId:       return "useGlobalId";
    case ID_categoryName:      return "categoryName";
    case ID_subsetName:        return "subsetName";
    case ID_index:             return "index";
    case ID_logical:           return "logical";
    case ID_requestedLayer:    return "requestedLayer";
    case ID_seedType:          return "seedType";
    case ID_honorOriginalMesh: return "honorOriginalMesh";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: OnionPeelAttributes::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
OnionPeelAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_adjacencyType:     return FieldType_enum;
    case ID_useGlobalId:       return FieldType_bool;
    case ID_categoryName:      return FieldType_string;
    case ID_subsetName:        return FieldType_string;
    case ID_index:             return FieldType_intVector;
    case ID_logical:           return FieldType_bool;
    case ID_requestedLayer:    return FieldType_int;
    case ID_seedType:          return FieldType_enum;
    case ID_honorOriginalMesh: return FieldType_bool;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: OnionPeelAttributes::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
OnionPeelAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_adjacencyType:     return "enum";
    case ID_useGlobalId:       return "bool";
    case ID_categoryName:      return "string";
    case ID_subsetName:        return "string";
    case ID_index:             return "intVector";
    case ID_logical:           return "bool";
    case ID_requestedLayer:    return "int";
    case ID_seedType:          return "enum";
    case ID_honorOriginalMesh: return "bool";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: OnionPeelAttributes::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
OnionPeelAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const OnionPeelAttributes &obj = *((const OnionPeelAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_adjacencyType:
        {  // new scope
        retval = (adjacencyType == obj.adjacencyType);
        }
        break;
    case ID_useGlobalId:
        {  // new scope
        retval = (useGlobalId == obj.useGlobalId);
        }
        break;
    case ID_categoryName:
        {  // new scope
        retval = (categoryName == obj.categoryName);
        }
        break;
    case ID_subsetName:
        {  // new scope
        retval = (subsetName == obj.subsetName);
        }
        break;
    case ID_index:
        {  // new scope
        retval = (index == obj.index);
        }
        break;
    case ID_logical:
        {  // new scope
        retval = (logical == obj.logical);
        }
        break;
    case ID_requestedLayer:
        {  // new scope
        retval = (requestedLayer == obj.requestedLayer);
        }
        break;
    case ID_seedType:
        {  // new scope
        retval = (seedType == obj.seedType);
        }
        break;
    case ID_honorOriginalMesh:
        {  // new scope
        retval = (honorOriginalMesh == obj.honorOriginalMesh);
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

